package com.wlyuan.open.domain.source.dispatcher.conversion;

import com.wlyuan.core.exception.AssertUtils;
import com.wlyuan.core.exception.ValueError;
import com.wlyuan.open.constants.CarrierTypeEnum;
import com.wlyuan.open.dto.OpenCombineQuotationSyncDTO;
import com.wlyuan.open.dto.OpenQuotationSyncDTO;
import com.wlyuan.open.infrastructure.exception.SourceValueErrorException;
import com.wlyuan.open.utils.LongUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Optional;

/**
 * @author lijing
 * @description
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class OpenDispatcherCombineQuotationConversion implements OpenDispatcherConversion<OpenCombineQuotationSyncDTO> {
    private final BaseOpenDispatcherConversion baseOpenDispatcherConversion;

    @Override
    public void convert(OpenCombineQuotationSyncDTO source) {
        convertTenant(source);
        convertWaybill(source);
        convertUp(source);
        convertDown(source);
        convertFees(source);
        convertMatch(source);
    }

    private void convertTenant(OpenCombineQuotationSyncDTO source) {
        source.setWaybillId(null);
        var tenant = source.getTenantId();
        if (LongUtils.notNullLong(tenant)) {
            var tenantId = baseOpenDispatcherConversion.tenant(tenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenCombineQuotationSyncDTO租户不存在:" + tenant), source);
            source.setTenantId(tenantId);
        }
    }

    private void convertWaybill(OpenCombineQuotationSyncDTO source) {
        var combine = source.getCombineId();
        if (LongUtils.notNullLong(combine)) {
            var combineId = baseOpenDispatcherConversion.combine(combine);
            AssertUtils.assertNotNull(combineId, new ValueError("OpenCombineQuotationSyncDTO合单不存在:" + combine), source);
            source.setCombineId(combineId);
        }
        var waybills = source.getWaybills();
        if (!CollectionUtils.isEmpty(waybills)) {
            waybills.forEach(spec -> {
                var waybillSpecId = baseOpenDispatcherConversion.transport(spec.getWaybillId());
                if (waybillSpecId == null) {
                    throw new SourceValueErrorException("OpenCombineQuotationSyncDTO合单子单不存在" + spec.getWaybillId());
                }
                spec.setWaybillId(waybillSpecId);
            });
        } else {
            throw new SourceValueErrorException("OpenCombineQuotationSyncDTO合单子单不能为空");
        }
    }

    private void convertUp(OpenCombineQuotationSyncDTO source) {
        var upStream = source.getCarrier();
        Optional.ofNullable(upStream).ifPresent(up -> {
            //租户
            var tenant = up.getTenantId();
            var tenantId = baseOpenDispatcherConversion.tenant(tenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenCombineQuotationSyncDTO upStream 租户不存在:" + tenant), source);
            up.setTenantId(tenantId);
            //承运方
            var carrierId = up.getCarrierId();
            var carrierType = up.getCarrierType();
            if (LongUtils.notNullLong(carrierId) || CarrierTypeEnum.isMyself(carrierType) || CarrierTypeEnum.isDriver(carrierType)) {
                var supplier = baseOpenDispatcherConversion.carrier(carrierId, carrierType, up.getTenantId());
                AssertUtils.assertNotNull(supplier, new ValueError("OpenCombineQuotationSyncDTO 承运方不存在:" + carrierId + "," + carrierType + "," + up.getTenantId()), source);
                up.setCarrierId(supplier.getCarrierId());
                up.setCarrierType(supplier.getCarrierType());
                if (StringUtils.isNoneBlank(supplier.getCarrierName())) {
                    up.setCarrierName(supplier.getCarrierName());
                }
            }
        });
    }

    private void convertDown(OpenCombineQuotationSyncDTO source) {
        var downStream = source.getCustomer();
        Optional.ofNullable(downStream).ifPresent(down -> {
            //租户
            var tenant = down.getTenantId();
            var tenantId = baseOpenDispatcherConversion.tenant(tenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenCombineQuotationSyncDTO downStream 租户不存在:" + tenant), source);
            down.setTenantId(tenantId);
            //客户
            var cId = down.getCustomerId();
            if (LongUtils.notNullLong(cId)) {
                var customer = baseOpenDispatcherConversion.customer(cId, down.getCustomerType(), tenantId);
                AssertUtils.assertNotNull(customer, new ValueError("OpenCombineQuotationSyncDTO downStream 客户不存在:" + cId + "," + down.getCustomerType() + "," + tenantId), down);
                down.setCustomerId(customer.getCustomerId());
                if (StringUtils.isNotBlank(customer.getCustomerName())) {
                    down.setCustomerName(customer.getCustomerName());
                }
            }
        });
    }

    private void convertFees(OpenQuotationSyncDTO source) {
        var fees = source.getFees();
        if (!CollectionUtils.isEmpty(fees)) {
            fees.forEach(f -> {
                var tenant = f.getTenantId();
                if (LongUtils.notNullLong(tenant)) {
                    var tenantId = baseOpenDispatcherConversion.tenant(tenant);
                    AssertUtils.assertNotNull(tenantId, new ValueError("OpenQuotationSyncDTO fee 租户不存在:" + tenant), source);
                    f.setTenantId(tenantId);
                }
                var user = f.getUserId();
                if (LongUtils.notNullLong(user)) {
                    var userId = baseOpenDispatcherConversion.user(user);
                    AssertUtils.assertNotNull(userId, new ValueError("OpenQuotationSyncDTO fee 用户不存在:" + user), source);
                    f.setUserId(userId);
                }
            });
        }
    }

    private void convertMatch(OpenQuotationSyncDTO source) {
        if (LongUtils.notNullLong(source.getTemplateId())) {
            var templateId = baseOpenDispatcherConversion.template(source.getTemplateId());
            AssertUtils.assertNotNull(templateId, new ValueError("OpenQuotationSyncDTO 合约不存在:" + source.getTemplateId()), source);
            source.setTemplateId(templateId);
        }
    }
}
